#include "data_structure/stack_link.h"
#include <string.h>

struct Stack_Node
{
    Stack_Node *prev; //上一个节点
    void *data;       //数据域
};

struct Stack
{
    Stack_Node *top;  //栈顶指针
    Stack_Node *base; //栈底指针
    int sizeof_type;  //当 Stack_Node->data 大小固定不变时，可设置该字段用以申请内存
    int stack_size;   //栈的大小
};

Stack *stack_creat(int sizeof_type)
{
    Stack *stack;

    stack = (StackPtr)malloc(sizeof(Stack));
    stack->top = stack->base = NULL;
    stack->sizeof_type = sizeof_type;
    stack->stack_size = 0;
    return stack;
}

int stack_destroy(StackPtr thisc)
{
    stack_clear(thisc);
    free(thisc);
    return 0;
}

int stack_clear(StackPtr thisc)
{
    if (!stack_empty(thisc))
        for (int i = 0; i < thisc->stack_size; i++)
            stack_pop(thisc);
    return 0;
}

bool stack_empty(StackPtr thisc)
{
    if (thisc->top == thisc->base)
        return true;
    return false;
}

int stack_size(StackPtr thisc)
{
    return thisc->stack_size;
}

bool stack_push(StackPtr thisc, const void *data)
{
    if (thisc == NULL)
        return false;
    if (thisc->sizeof_type == 0)
        return false;
    Stack_NodePtr node = (Stack_NodePtr)malloc(sizeof(Stack_Node));
    node->data = (void *)malloc(thisc->sizeof_type);
    memcpy(node->data, data, thisc->sizeof_type);
    node->prev = thisc->top;
    thisc->top = node;
    thisc->stack_size++;
    return true;
}

const void *stack_top(StackPtr thisc)
{
    if (thisc->stack_size == 0)
        return NULL;
    return thisc->top->data;
}

bool stack_pop(StackPtr thisc)
{
    if (thisc->top != thisc->base)
    {
        free(thisc->top->data);
        Stack_NodePtr p = thisc->top;
        thisc->top = thisc->top->prev;
        free(p);
        return true;
    }
    return false;
}
